import LoginVue from '@/views/Login.vue'
import Cookies from 'js-cookie'
import { createRouter, createWebHashHistory, type RouteLocationNormalized, type RouteRecordRaw } from 'vue-router' //createWebHistory历史模式
// import HomeView from '../views/HomeView.vue'

import { useUserInfoStore } from "@/stores/userInfo"
import * as api from '@/request/api'

const router = createRouter({
  // history: createWebHistory(import.meta.env.BASE_URL),//历史模式
  history: createWebHashHistory(),
  routes: [
    {
      path: "/login",
      name: "login",
      component: LoginVue,
    },
    {
      path: "/",
      redirect: "/index",//重定向到子路由，仍然渲染组件，routerview则显示该重定向的子路由；必须要有routerview，否则只跳转路由。
      component: () => import('../views/Layout.vue'),
      children: [
        {
          path: "/index",
          component: () => import('../views/HomeView.vue')
        }
      ]
    },
    {
      path: '/pinia',
      name: 'pinia',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/Pinia.vue')
    }
  ]
})


// 【路由守卫】由于菜单栏信息管理员、用户不一样，所以最好是动态获取，而不能设置缓存。
// 我们发现，在每次刷新时pinia都会清空，因此，可以在每次访问页面前再次获取数据存进pinia。
// 所以，在router.beforeEach( callback ) 全局前置守卫书写相关逻辑
// console.log("222222222222");
let b: RouteLocationNormalized;

router.beforeEach(async (to, from, next) => {
  // console.log(to, from);

  // 【A】访问页面前
  // A.0 分为：已登录 和 未登录。
  // 已登录分为：
  // a 有token但是仓库菜单为空————还没有进行第一次请求；或者进行刷新操作。————进行请求获取token + menu数据，再放行，故自动跳到c。
  // b 有token但是仓库菜单非空，跳转到"/login"————不放行，跳回原页面
  // c 有token但是仓库菜单非空，跳转到其他————放行。
  // 未登录分为：
  // 无token，且跳转页非login————不放行，跳回login
  // 无token，且跳转页为login；无token刷新...————放行

  const token = Cookies.get("token");

  // https://pinia.web3doc.top/core-concepts/outside-component-usage.html
  const userInfoStore = useUserInfoStore();//必须在创建路由后，此时仓库也已经创建，获取仓库实例。
  const menus = userInfoStore.menus;

  // A.1 已登录且没数据，：如果有token，且pinia菜单为空，就去获取数据。
  // console.log("111111");
  if (token && !menus.length) {
    // 发送请求，异步方式
    // try - catch 
    // 如果请求失败走catch
    try {
      // A.1.1 请求成功。
      const { menus, username, roles } = await api.admin.getAdminInfo();
      userInfoStore.updateUserInfo(menus, username, roles);



      // 【动态添加路由】
      // 获取仓库里过滤后的数据。
      userInfoStore.sortedMenu.forEach(el => {

        // 重定向到第一个子目录
        // RouteRecordRaw从router.addRoute，限制children类型。
        let dynamicRoutes: RouteRecordRaw = {
          path: "/" + el.name,
          redirect: `/${el.name}/${el.children![0].name}`,
          component: () => import('../views/Layout.vue'),
          children: [],
        };

        el.children?.forEach(item => {
          dynamicRoutes.children?.push({
            path: item.name,
            component: () => import(`../views/${el.name}/${item.name}.vue`)
          })
        })
        router.addRoute(dynamicRoutes);
      })


      next(to.fullPath);
      // next({ ...to, replace: true })

      // next(to.fullPath);和next()的区别
      // next();是放行，共访问一次
      // next(to.fullPath);是跳转，一共访问两次

    } catch (e) {
      // A.1.2 请求失败，可能是token过期，转到login重新登录
      Cookies.remove("token")
      next("/login")
    }
  } else if (token && to.fullPath === "/login") {
    // A.2 登录后，路由跳转login
    next(from.fullPath);//跳回原来页面
  } else if (!token && to.fullPath !== "/login") {
    // A.3 未登录，不跳转到login
    next("/login")
  } else {
    next();
  }
})


export default router
